<?php

/*
	swoole.websocket 服务端类
	需要安装swoole模块
	swoole 版本号: 2.0.12
*/
namespace Src;

class WebSocket {

	public $host;	//监听地址
	public $port;	//监听端口号
	public $config;	//swoole 设置
	private $swoole;	//swoole 服务
	private $table;	//共享库
	public $db;

	public function __construct($host, $port, $config, $db){
		$this->host = $host;
		$this->port = $port;
		$this->config = $config;
		$this->db = $db;
	}

	// 开启服务

	public function run(){
		$this->swoole = new \swoole_websocket_server($this->host, $this->port);
		$this->swoole->set($this->config['ws_conf']);
		$this->swoole->on('open',array($this,'open'));
		$this->swoole->on('message',array($this,'message'));
		$this->swoole->on('close',array($this,'close'));

		
		$this->create_table();
		$this->swoole->start();
	}


	//连接事件
	public function open($serv, $request){
		try{
			if(!isset($request->get['token'])){
				$this->end($serv,$request->fd,array('status'=>2,'msg'=>'token not found'));
				return ;
			}
			//保存用户信息到共享库
			$this->save_info($serv, $request);
		}catch(Exception $e){
			$this->end($serv,$request->fd,array('status'=>1,'msg'=>'service error'));
			return ;
		}
	}

	//消息事件
	public function message($serv, $frame){
		try{
			//检查data数据包的类型和完整性
			if($frame->finish && ($frame->opcode == 1)){
				//广播
				$this->loop_message($serv, $frame->fd, $frame->data);

				//保存消息数据
				if($this->save_message($frame->fd, $frame->data)){
					$this->msg($serv, $frame->fd, array('status'=>0,'msg'=>'ok'));
				}
			}
		}catch(Exception $e){
			
		}
	}

	//断开事件
	public function close($serv, $fd){
		try{
			//断开连接 清除用户信息
			$this->table->del($fd);
		}catch(Exception $e){
			
		}
	}

	//创建共享库
	private function create_table(){
		$this->table = new \swoole_table(1024);
		$this->table->column('fd',\swoole_table::TYPE_INT);
		$this->table->column('type',\swoole_table::TYPE_INT); //type 1 为直播 type 2 为录播
		$this->table->column('code',\swoole_table::TYPE_STRING,255);//所属评论id
		$this->table->column('nickname',\swoole_table::TYPE_STRING,100);//用户昵称
		$this->table->column('thumb',\swoole_table::TYPE_STRING,255);//用户头像
		$this->table->column('userid',\swoole_table::TYPE_INT);//用户ID

		$this->table->create();
	}

	//遍历发送消息
	private function loop_message($serv, $fd, $message){
		//取出push消息的用户信息
		$user = $this->table->get($fd);
		$time = date('Y-m-d H:i:s',time());
		foreach($this->table as $v){
			//剔除不属于该视频消息和自己的信息
			if($v['fd'] == $fd || ($user['code']!=$v['code'])){
				continue;
			}
			$data = array(
				'message'	=>	$message,
				'nickname'	=>	$user['nickname'],
				'thumb'	=>	$user['thumb'],
				'time'	=>	$time
			);
			
			$this->msg($serv ,$v['fd'], $data);
		}
	}


	//保存评论消息
	private function save_message($fd,$message){
		$user = $this->table->get($fd);

		$link = $this->db->get();
		if(!$link){
			$this->end($serv,$request->fd,array('status'=>3,'msg'=>'busy service'));
			return ;
		}
		$sql = "insert into comments set mem_id={$user['userid']},comm_pid=0,comm_time='".time()."',content='";
		$sql .= htmlentities($message)."',";
		if($user['type']==1){
			$sql .= "live_markcode={$user['code']},video_id=''";
		}else{
			$sql .= "video_id={$user['code']},live_markcode=''";
		}
		//查询用户信息
		$data = $this->db->query($link,$sql);
		//返还数据库资源
		$this->db->release($link);

		if($data){
			return true;
		}else{
			return false;
		}
	}

	//查询用户信息
	private function save_info($serv, $request){
		$link = $this->db->get();
		if(!$link){
			$this->end($serv,$request->fd,array('status'=>3,'msg'=>'busy service'));
			return ;
		}
		//查询用户信息
		$sql = "select id,nickname,thumb from member where token='{$request->get['token']}'";
		$data = $this->db->query($link,$sql);
		//返还数据库资源
		$this->db->release($link);

		if($data){
			//获取到用户信息 准备数据
			$user = array(
				'fd'	=>	$request->fd,
				'type'	=>	$request->get['live_markcode']?1:2,
				'code'	=>	$request->get['live_markcode']?$request->get['live_markcode']:$request->get['video_id'],
				'nickname'	=>	$data[0]['nickname'],
				'userid'	=>	$data[0]['id'],
				'thumb'	=>	$data[0]['thumb']
			);
			//存入用户链接信息
		 	$this->table->set($request->fd, $user);
		 	$this->msg($serv,$request->fd,array('status'=>0,'msg'=>'link start!'));
		}else{
			$this->end($serv,$request->fd,array('status'=>4,'msg'=>'token invalid'));
			return ;
		}
	}

	//发送
	private function msg($serv, $fd, array $data){
		$serv->push($fd,json_encode($data));
	}

	//终止信息
	private function end($serv, $fd, array $data){
		$serv->push($fd,json_encode($data));
		$serv->close($fd);
	}
}

